package gas.controller;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

import gas.model.*;
/**
 * 
 * Has the instance of the Userbase and GasStationBase and makes calls
 * to Model Subsystem functions.
 * 
 * @author cs120fao
 *
 */
public class ModelController {
  private static UserBase userBase = new UserBase(); //static?
  private static GasStationBase stationBase = new GasStationBase();
  public static PriorityQueue<GasStationAdapter> currentGasList = null;
  public static User currentUser = null;
  
  public ModelController(){};
  
  public static UserBase getUserBase(){
      return userBase;
  }
  public static GasStationBase getStationBase(){
      return stationBase;
  }
  
  /***
   *  
   * @param u
   * @param p
   * @param e
   * @param l
   * @return
   */
  public static boolean createUser( String u, String p, String e, boolean l){
        
        if (l) currentUser = userBase.createUserAccount(u,p,e, 0);
        else userBase.createUserAccount(u,p,e, 0);

        if ( currentUser != null ) System.out.println("Successfully Logged in");
        else return false;
      
        return ( currentUser != null ) ? true : false;
  }
  public static boolean createUser( String u, String p, String e, Integer id, boolean isAdmin, boolean l){
    if (l) currentUser = userBase.createUserAccount(u,p,e, id);
    else userBase.createUserAccount(u,p,e, id);
    
    if ( isAdmin ) userBase.upgradeUser(id);
    
    if ( currentUser != null ) System.out.println("Successfully Logged in");
    else return false;
  
    return ( currentUser != null ) ? true : false;
  }
  
  public static boolean createStation( String sn, String cp, LocationsEnum LE){//String loc){
        int dollarAmount = Integer.parseInt(cp);
        stationBase.newStation(sn, dollarAmount, LE);
        
        return true;
    }
  
  public static boolean isLoggedIn(){
     return (currentUser != null) ? true : false;
  }
  
  //TODO: LOGIN
  /***
   * login(String, String) asks if the user is present, and if it is, checks to
   * see if the password matches with the user.
   */
  public static boolean login(String userName, String password){
      boolean loggedIn = false;
      User checkUser = userBase.getUser(userName);
      if(checkUser == null);
      else{
        loggedIn = password.equals(checkUser.getPassword());
        if(loggedIn) currentUser = checkUser;
      }
      return loggedIn;
  }
  
  //TODO: Add back button in Create Account
  //TODO: Add back button in Log In
  
  public class GasStationAdapter{
      public GasStation gs;
      public int compatibilityValue;
      private int maxCompatibility;
      public ArrayList<Integer> timeAt;

      public GasStationAdapter(GasStation g, int cv){
          gs = g;
          compatibilityValue = cv;
      }  
      public void setTime(ArrayList<Integer> compatibleTimes){ timeAt = compatibleTimes; }
      public int getCV( ){return compatibilityValue;}
      public float getCompatability(){ return (float)compatibilityValue/(float)maxCompatibility; }
      public ArrayList<Integer> getTimes(){ return timeAt; }
  }
  
  public class GsComparator implements Comparator<GasStationAdapter>{
      public int compare(GasStationAdapter x, GasStationAdapter y)
      {
          // Assume neither string is null. Real code should
          // probably be more robust
          if (x.compatibilityValue < y.compatibilityValue ) return 1;
          if ( x.compatibilityValue > y.compatibilityValue ) return -1;
          return 0;
      }
  }
  
  public static boolean getMatchingStations(){
      ModelController testMC = new ModelController();
      Comparator<GasStationAdapter> comparator = testMC.new GsComparator();
      PriorityQueue<GasStationAdapter> retGasList = new PriorityQueue<GasStationAdapter>(10, comparator);
      
      for(GasStation gs : stationBase.getGasTable()){
          
          Preferences comparePrefs = currentUser.getPrefs();
          int currentCV = 0;
          
       // Calculates compatibility by matching price.
          ArrayList<Integer> compatibleTimes = new ArrayList<Integer>();
          if ( (comparePrefs.getCostValue()) > gs.getCurrentPrice() ){
                currentCV += 10;
          }
       // Calculates compatibility by matching wait times.
          for(int i = 0; i < 24; i++){
            if ( comparePrefs.getWaitTolerance() > gs.getPopularity(i) ){
                compatibleTimes.add(new Integer(i));
                currentCV++;
            }
          }
       // TODO: Allow for Compatibility calculation for location.
          if( comparePrefs.getLocation().equals(gs.getLocation()) )
              currentCV += comparePrefs.getProximityValue();
          
          GasStationAdapter GSA = testMC.new GasStationAdapter(gs, currentCV);
          GSA.setTime(compatibleTimes);
          GSA.maxCompatibility = 24 + 10 + comparePrefs.getProximityValue();

          retGasList.add(GSA);
      }

      currentGasList = retGasList;
      return (retGasList.size() != 0);
  }

  public static GasStationAdapter getGasStation(int i){
      return (GasStationAdapter)(currentGasList.toArray()[i]);
  }
  
  //TODO: LOGOUT
  public static void logout(){
    currentUser = null;
  }
  /*
    private int proximityValue; // how close you want the station to be.
    private int costValue; // how cheap you want the station to be.
    private int roundTripCost; // pricePerGallonRange
    private int waitTolerance;
   */ 
  //TODO: Set Preferences.
  public static void setPreferences( int proxV, int costV, int roundCost,  int waitTolerance){
      if(!isLoggedIn()) return;
      
  }
}
